/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mamayukero.main;
import java.awt.Color;
import java.awt.event.*;
import java.io.File;
import java.text.DecimalFormat;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import mamayukero.problem.environment.Environment;
import mamayukero.problem.environment.component.Machine;
import mamayukero.problem.environment.component.Vendor;
import mamayukero.problem.environment.map.Const;
import mamayukero.ui.environment.UIEnvironment;
import mamayukero.ui.ga.UIVisualisasi;
import mamayukero.problem.environment.Timer;
/**
 *
 * @author Dell
 */
public class MainGUI {
    
    public MainGUI()
    {
        //inisialisasi kelas environment
        Environment.Reset();
        Environment.load(Const.FILE_INPUT);
        initComponents();
        
        //coba cetak isi map.
         mainFrame.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                 //periksa apakah mouse berada di area map
            }
        });
         mainFrame.setFocusable(true);
     }
     private void initComponents()
    {

      //inisialisasi uiTimer
        timerOn = false;
        uiTimer = new javax.swing.Timer(200, new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                timerOn = true;
                if (!Environment.timesUp())
                {
                    nextStep();            
                }
                else
                {
                    timerOn = false;
                    uiTimer.stop(); // ya, ngestop diri sendiri.
                }
            }
        }
                
                );
        
        
        
      //manual dulu, nanti bagian-bagian ini bisa diambil dari data class lain
        width = 800;
        height = 600;
        mapwidth = 500;
        mapheight = 500;
       // uang = 150000;
      //pathfinding state
        pfstate = 0;
        
      //setting boolean yang memeriksa apakah map sedang menyorot seuatu area atau tidak.
       // isClick = false;
      //FILECHOOSER
        fchooser = new JFileChooser();
        
      //FORMAT
        df = new DecimalFormat("#.##");
        
      //MAINFRAME
        mainFrame = new JFrame("Genetic Algorithm Simulation");
        mainFrame.setSize(width, height);
        mainFrame.setVisible(true);
        mainFrame.setLayout(null);
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
     //MENUBAR
        menuBar = new JMenuBar();
        menuBerkas = new JMenu();
        menuSim = new JMenu();
        bukaBerkas = new JMenuItem();
        simpanLog = new JMenuItem();
        nextStep = new JMenuItem();
        autoStep = new JMenuItem();
        finishStep = new JMenuItem();
        GAOp = new JMenuItem();
        machData = new JMenuItem();
        
        
        
        //set menu item
        menuBerkas.setText("File");
        
        bukaBerkas.setText("Open File..");
        bukaBerkas.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        bukaBerkas.addActionListener(new ActionListener(){
            @Override
                public void actionPerformed(ActionEvent evt)
                    {
                        int returnVal = fchooser.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File flx = fchooser.getSelectedFile();
            mainFrame.dispose();
            Environment.Reset();
            Environment.load(flx.getPath());
            
            initComponents();
            
        }
                    }
                });
        
          
        simpanLog.setText("Save Log File..");
        simpanLog.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        simpanLog.addActionListener(new ActionListener(){
            @Override
                public void actionPerformed(ActionEvent evt)
                    {
                        int returnVal = fchooser.showSaveDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File flx = fchooser.getSelectedFile();
            Environment.writeReport(flx);
            
        }
                    }
                });
        
        menuSim.setText("Simulation");
        
        nextStep.setText("Next Step");
        nextStep.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_T,0));
        nextStep.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt)
            {
               nextStep();
            }
        }
                
                );
        
        autoStep.setText("Autorun Step");
        autoStep.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_R,0));
        autoStep.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt)
            {
                autoStep();
            }
        }
                
                );
        
        finishStep.setText("Finish Step / Solution");
        finishStep.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_F,0));
        finishStep.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt)
            {
                finishStep();
            }
        }
                
                );
        
        
        GAOp.setText("Configure GA");
        GAOp.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_G,0));        
        GAOp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt)
            {
                UIVisualisasi uiGA = new UIVisualisasi();
                uiGA.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            }
        }
                
                );
        
        machData.setText("Machine Data");
        machData.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_D,0));
       
        
        menuBerkas.add(bukaBerkas);
        menuBerkas.add(simpanLog);
        menuSim.add(nextStep);
        menuSim.add(autoStep);
        menuSim.add(finishStep);
        menuSim.add(GAOp);
        //menuSim.add(machData);
        menuBar.add(menuBerkas);
        menuBar.add(menuSim);
        //terakhir, pasang menubar
        mainFrame.setJMenuBar(menuBar);
        
     //INFOPANEL   
        infoPanel = new JPanel();
        infoPanel.setBackground(new java.awt.Color(204, 204, 255));
        infoPanel.setBorder(BorderFactory.createEtchedBorder());   
        infoPanel.setBounds(10, 30, 250, 500);
        infoPanel.setLayout(null);
        
        //masukkan labelSorot
        labelSorot = new JLabel(infoHead);
        labelSorot.setFont(new java.awt.Font("Segoe UI", 1, 15));
        labelSorot.setBounds((infoPanel.getWidth()-200)/2,0,200,40); 
        infoPanel.add(labelSorot);
        
        //
 
        //siapkan tabel untuk datapanel       
        tab1 = new JTable();
        /*tab1.setModel(new javax.swing.table.DefaultTableModel(
                new String[][]{{"M1","OFF","0"},{"M2","OFF","0"}}, new String[]{"Machine","Status","Products"})
                );*/
        tab1.setPreferredScrollableViewportSize(new java.awt.Dimension(70,100));
        tab1.setFillsViewportHeight(true);
        
        //masukkan tabel ke panel data
        dataPanel = new JScrollPane(new JScrollPane(tab1));        
        dataPanel.setBounds(20, 40, infoPanel.getWidth()-40, 150);
        //masukkan ke panel utama
        infoPanel.add(dataPanel);
        
        //masukkan separator
        sep1 = new JSeparator();
        sep1.setBounds(dataPanel.getBounds().x, dataPanel.getBounds().y+dataPanel.getHeight()+10, infoPanel.getWidth()-(2*(dataPanel.getBounds().x)), dataPanel.getHeight());
        infoPanel.add(sep1);
        
        //masukkan label truk
        labelTruk = new JLabel("Main Truck");
        labelTruk.setFont(new java.awt.Font("Segoe UI", 1, 15));
        labelTruk.setBounds((infoPanel.getWidth()-80)/2, sep1.getBounds().y, 80, 40);
        infoPanel.add(labelTruk);
        
        
        //siapkan tabel untuk data truk
        tab2 = new JTable();
        /*tab2.setModel(new javax.swing.table.DefaultTableModel(
                new String[][]{{"M1","M2","M3","M4","M5"},{"M6","M7","M8","M9","M10"}}, new String[]{"1","2","3","4","5"})
                );*/
        tab2.setTableHeader(null);
        tab2.setPreferredScrollableViewportSize(new java.awt.Dimension(infoPanel.getWidth()-70,100));
        tab2.setFillsViewportHeight(true);
        //masukkan data truk        
        dataTruk = new JScrollPane(new JScrollPane(tab2));
        dataTruk.setBounds(dataPanel.getBounds().x, sep1.getBounds().y+40, infoPanel.getWidth()-40 , 50);
        infoPanel.add(dataTruk);
        
        //buat label pathTruk
        pathTruk = new JLabel("Path (click to change)");
        pathTruk.setFont(new java.awt.Font("Segoe UI", 1, 13));
        pathTruk.setBounds((infoPanel.getWidth()-80)/16, dataTruk.getBounds().y+dataTruk.getHeight()+10, 150, 20);
        infoPanel.add(pathTruk);
       
        //buat tombol untuk ngubah pathTruk
        pathBtn = new JButton("A*");
        pathBtn.setBounds((infoPanel.getWidth()-80)/2, pathTruk.getBounds().y+pathTruk.getHeight()+10, 80, 30);
        infoPanel.add(pathBtn);
        pathBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e){
               changePath();
            }
        });
        
        
        //separator kedua
        sep2 = new JSeparator();
        sep2.setBounds(dataPanel.getBounds().x, pathBtn.getBounds().y+pathBtn.getHeight()+10,infoPanel.getWidth()-(2*(dataPanel.getBounds().x)), pathTruk.getHeight());
        infoPanel.add(sep2);
                
        //pasang labelUsaha
        labelUsaha = new JLabel("Corporation Data");
        labelUsaha.setFont(new java.awt.Font("Segoe UI", 1, 15));
        labelUsaha.setBounds((infoPanel.getWidth()-130)/2, sep2.getBounds().y, 130, 40);
        infoPanel.add(labelUsaha);
        
        //pasang data uang
        labelUang = new JLabel(accHead);
        labelUang.setFont(new java.awt.Font("Segoe UI", 1, 13)); 
        labelUang.setBounds((infoPanel.getWidth()-80)/16, sep2.getBounds().y+labelUsaha.getHeight(), sep2.getWidth(), 20);
        infoPanel.add(labelUang);
       
        //coba nambah teks
        labelUang.setText(accHead+Environment.startingMoney);
       
        //pasang data waktu
        labelWaktu = new JLabel(Timer.whatTime());
        labelWaktu.setFont(new java.awt.Font("Segoe UI", 1, 13));
        labelWaktu.setBounds((infoPanel.getWidth()-80)/16, sep2.getBounds().y+labelUsaha.getHeight()+labelUang.getHeight(), sep2.getWidth(), 20);
        infoPanel.add(labelWaktu);
        
        //pasang data profit
        labelProfit = new JLabel("Profit : "+df.format(Environment.map.factory.countProfit())+"%");
        labelProfit.setFont(new java.awt.Font("Segoe UI", 1, 13));
        labelProfit.setBounds((infoPanel.getWidth()-80)/16, sep2.getBounds().y+labelUsaha.getHeight()+labelUang.getHeight()+labelWaktu.getHeight(), sep2.getWidth(), 20);
        infoPanel.add(labelProfit);
       
        
     //pasang infopanel
        mainFrame.getContentPane().add(infoPanel);   
        

     //UIENVIRONMENT
          
        //siapkan gambar environment
        uiEnvironment = new UIEnvironment(mapwidth, mapheight);
        uiEnvironment.setBackground(new java.awt.Color(250, 232, 174));
        uiEnvironment.setBorder(BorderFactory.createTitledBorder(null, "Main Map", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.TOP, new java.awt.Font("Segoe UI", 1, 18),new java.awt.Color(255,255,237))); // NOI18N
        uiEnvironment.setBounds(infoPanel.getX()+infoPanel.getWidth()+10, infoPanel.getY(), mapwidth,mapheight);
                
        //pasang environment
        mainFrame.add(uiEnvironment);
        mainFrame.setFocusable(true);
        
      //pengaturan warna!
      colorSet();
      //updateTime();
    }
    
     public static void main (String args[])
    {
        Environment.Reset();
        Environment.load(Const.FILE_INPUT);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MainGUI();
            }
        });
    }
     
    public static void updateInfo()
    {  dm = (DefaultTableModel) tab1.getModel();
       dm.getDataVector().removeAllElements();
       
       if(UIEnvironment.isClicked == true)        
            {
                if(UIEnvironment.xMap[UIEnvironment.clickedLocation.x][UIEnvironment.clickedLocation.y] == 2)
                {
                    //clicked factory
                    labelSorot.setText("Factory");
                    
                    //hapus data tabel saat ini
                    //isi dengan data factory

                     machnums = new String[Environment.map.factory.sizeMachine()][3];
                     int i = 0;
                     for(Machine m: Environment.map.factory.getContainer())
                     {
                         machnums[i][0] = "M"+m.type;                        
                         machnums[i][1] = " "+ (m.isActive ? "ON" : "OFF");
                         machnums[i][2] = " "+Environment.map.factory.production[m.type-1];
                         i++;
                     }
                     //masukkan data mesin.
              
                     tab1.setModel(new javax.swing.table.DefaultTableModel(machnums,new String[]{"Machine","Status","Products"}));

                }
                else if(UIEnvironment.xMap[UIEnvironment.clickedLocation.x][UIEnvironment.clickedLocation.y] == 3)
                {
                    //cari vendor
                    for(Vendor v:Environment.map.vendor)
                    {
                        if(v.getLocation().x == UIEnvironment.clickedLocation.x && v.getLocation().y == UIEnvironment.clickedLocation.y)
                        {   

                            labelSorot.setText("Vendor "+v.name);

                           //isi dengan data vendor

                               machnums = new String[1][v.sizeMachine()];
                               int i = 0;
                               for(Machine m: v.getContainer())
                                {
                                    machnums[0][i] = "M"+m.type;
                                    i++;
                                }
                               
                               
                     tab1.setModel(new javax.swing.table.DefaultTableModel(machnums,new String[]{"Available Machines"}));

                        }
                    }
                }
                else
                {
                    labelSorot.setText(infoHead);
                }
            }
            else
            {
                labelSorot.setText(infoHead);
            }
            //tab1.setTableHeader(null);
           tab1.repaint();
    }
    
    public static void updateTruckInfo()
    {
        dm = (DefaultTableModel) tab2.getModel();
        dm.getDataVector().removeAllElements();
        
       machnums = new String[(Environment.map.truck.capacity-1/5)+1][5];
                     
       int i = 0;
       int j = 0;
        for(Machine m: Environment.map.truck.machines)
       {
           if(j == 4)
           {
               i++;
               j = 0;
           }
           machnums[i][j] = "M"+m.type;
           j++;
       }
       tab2.setModel(new javax.swing.table.DefaultTableModel(
                machnums, new String[]{"1","2","3","4","5"})
                );
       tab2.repaint();
    }
    
    
    public void changePath()
    {
         if(pfstate == 2)
                {
                    pfstate=0;
                }
                else{pfstate++;}
                Environment.map.truck.pfstate = pfstate;
                switch(pfstate){
                    case 0 :
                        pathBtn.setText("A*");
                        break;
                    case 1 :
                        pathBtn.setText("BFS");
                        break;
                    case 2 :
                        pathBtn.setText("Greedy");
                        break;
                }
 
        
    }
    
    public static void updateMoney()
    {
        labelUang.setText(accHead+Environment.currentMoney);
    }
    
    public static void updateTime()
            // t adalah menit
    {
       labelWaktu.setText(Timer.whatTime());
        
     /*   if(t<60)
        {
            labelWaktu.setText(timeHead+t+" mins.");
        }
        else
        {
            labelWaktu.setText(timeHead+(t/60)+" hours "+(t%60)+" mins.");
        }
       */ 
    }
    
    public void updateProfit()
    {
        double profit = Environment.map.factory.countProfit();
        labelProfit.setText(profit < 0? 
                "Defisit :" + df.format(-1*Environment.map.factory.countProfit())+"%":
                "Profit :" + df.format(Environment.map.factory.countProfit())+"%");
    }
    
    public void nextStep()
    {
        Environment.turn();
        updateInfo();
        updateTruckInfo();
        updateTime();
        updateMoney();
        updateProfit();
        uiEnvironment.repaint();
    }
    
    public void autoStep()
    {
        uiTimer.start();
    }
    
    public void finishStep()
    {
        if(timerOn) //kalau delay nyala
        {timerOn = false;
         uiTimer.stop();
        }
         while (!Environment.timesUp())
        {
            Environment.turn();
        updateInfo();
        updateTruckInfo();
        updateTime();
        updateMoney();
        updateProfit();
        }
         //didrawnya terakhir   
         uiEnvironment.repaint();            
                 
    }
    public void colorSet()
    {
       mainFrame.getContentPane().setBackground(new java.awt.Color(217,189,143));
       menuBar.setBackground(new java.awt.Color(186, 168, 116));
       menuBar.setBorderPainted(false);
       infoPanel.setBackground(new java.awt.Color(88, 138, 127));
       uiEnvironment.setBackground(new java.awt.Color(255, 138, 82));
       labelSorot.setForeground(new java.awt.Color(231,230,255));
       labelTruk.setForeground(new java.awt.Color(231,230,255));
       pathTruk.setForeground(new java.awt.Color(231,230,255));
       labelUang.setForeground(new java.awt.Color(231,230,255));
       labelUsaha.setForeground(new java.awt.Color(231,230,255));
       labelWaktu.setForeground(new java.awt.Color(231,230,255));
       labelProfit.setForeground(new java.awt.Color(231,230,255));       
       tab1.setBackground(new java.awt.Color(245,240,171));
       tab2.setBackground(new java.awt.Color(245,240,171));
       pathBtn.setBackground(new java.awt.Color(217,176,102));
       pathBtn.setForeground(new java.awt.Color(231,255,255));
       pathBtn.setFont(new java.awt.Font("Segoe UI", 1, 13));
    }
    
     //dibawah ini list variabel, ditaruh di bawah supaya mudah dirubah :D
    private int width, height;
    private int mapwidth, mapheight;
    private static String infoHead = new String("No Vendor/Factory Selected");
    private static String accHead = new String("Account : Rp ");
    private static String timeHead = new String("Time Elapsed : ");
    public int pfstate; //penampung state pathfinding
    private JFrame mainFrame;
    private JMenuBar menuBar;
    private JMenu menuBerkas;
    private JMenu menuSim;
    private JMenuItem bukaBerkas;
    private JMenuItem simpanLog;
    private JMenuItem nextStep;
    private JMenuItem autoStep;
    private JMenuItem finishStep;
    private JMenuItem GAOp;
    private JMenuItem machData;
    private static JPanel infoPanel;
    private JScrollPane dataPanel; // penampung tab1
    private UIEnvironment uiEnvironment;
    private static JLabel labelSorot;
    private JSeparator sep1; //separator biasa
    private JSeparator sep2;
    private static JTable tab1; //tabel untuk informasi mesin dll
    private static JTable tab2; //untuk informasi barang yang dibawa oleh truk
    private static DefaultTableModel dm;
    private static String[][] machnums;
    private JLabel labelTruk;
    private JLabel pathTruk;
    private JButton pathBtn;
    private JScrollPane dataTruk;
    private JLabel labelUsaha;
    private static JLabel labelUang;
    private static JLabel labelWaktu;
    private static JLabel labelProfit;
    private JFileChooser fchooser;
    private javax.swing.Timer uiTimer ;
    private boolean timerOn;
    private DecimalFormat df;
    
}
